package com.fdb.efp.nls.service.impl.yed;

import com.fdb.basic.framework.core.base.FrameworkService;
import com.fdb.basic.framework.core.constant.FilePathConstant;
import com.fdb.basic.framework.core.util.DateTool;
import com.fdb.basic.framework.core.util.SFTPUtil;
import com.fdb.basic.framework.core.util.StringUtil;
import com.fdb.basic.framework.core.util.UUIDUtil;
import com.fdb.efp.console.common.PrdBizEnums;
import com.fdb.efp.nls.service.vo.ImageBizDetailVO;
import com.fdb.efp.nls.service.vo.LogErrorInfoVO;
import com.fdb.efp.nls.common.bo.UpLoadFileVO;
import com.fdb.efp.nls.service.vo.YedImageFileInfoVO;
import com.fdb.efp.nls.service.domain.TxtFileLoadBean;
import com.fdb.efp.nls.service.facade.ImageBizDetailService;
import com.fdb.efp.nls.service.facade.LogErrorInfoService;
import com.fdb.efp.nls.service.facade.UpLoadFileService;
import com.fdb.efp.nls.service.facade.yed.YedImageFileAnalysisService;
import com.fdb.efp.nls.service.util.TxtFileLoadPlugin;
import com.fdb.efp.esb.common.constant.ElectronicSignatureEnums;
import com.fdb.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.fdb.efp.nls.service.vo.sx.NlsCreditInfoVO;
import com.jcraft.jsch.ChannelSftp;
import com.sunyard.client2.FileNameEnums;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.*;

/**
 * 需求编号：xxxxxx<br/>
 * 问题编号：<br/>
 * 功能描述：交互文件服务-影像文件解析<br/>
 * 创建时间：2020/8/14 18:24
 * @Author tiankg
 * @Version 1.0
 * @Since 1.0
 */
@Service("yedImageFileAnalysisService")
public class YedImageFileAnalysisServiceImpl implements YedImageFileAnalysisService, FrameworkService {

    private static Logger logger = LoggerFactory.getLogger(YedImageFileAnalysisServiceImpl.class);

    @Value("${analysis.yed.imageFilePath}")
    private String imageFilePath ;// 影像文件解析路径

    @Value("${analysis.downNum}")
    private int downNum;// 影像文件下载最多个数

    @Value("${file.yed.remoteImagesDownPath}")
    private String remoteImagesDownPath;// 前置文件服务器：影像文件下载地址

    @Value("${analysis.yed.imageFileName}")
    private String imageFileName ;// 影像文件名称

    @Value("${analysis.yed.imageOKFileName}")
    private String imageOKFileName ;// 影像ok文件名称

    @Value("${yed.ftp.host}")
    private String host;// 前置文件服务器IP地址

    @Value("${yed.ftp.username}")
    private String username;// 前置文件服务器用户名

    @Value("${yed.ftp.pwd}")
    private String pwd;// 前置文件服务器登录密码

    @Value("${yed.ftp.port}")
    private int port;// 前置文件服务器端口号

    @Autowired
    @Qualifier("logErrorInfoService")
    private LogErrorInfoService logErrorInfoService;// 异常信息表

    @Autowired
    @Qualifier("upLoadFileService")
    private UpLoadFileService upLoadFileService;// 上传影像信息表

    @Autowired
    @Qualifier("imageBizDetailService")
    private ImageBizDetailService imageBizDetailService;

    @Autowired
    @Qualifier("nlsCreditInfoService")
    private NlsCreditInfoService nlsCreditInfoService;

    /**
     *
     * 交互文件服务-影像文件解析
     *
     * @param
     * @return
     * @throws Exception
     * @author ludayong
     * @since 2019年1月2日 下午7:06:52
     * @version 1.0
     */
    @Override
    public synchronized boolean analysisImageFile(String batchDate) {
        long startTime = System.currentTimeMillis();
        logger.info("前置文件服务器获取优e贷影像文件：[" + batchDate + "]， 处理开始！");
        // 连接前置文件服务器
        SFTPUtil sftpUtil = null;
        // 下载文件是否成功
        boolean fileDownRes = false;
        int downTotal = 0;
        // 文件目录
        String localPath = imageFilePath;
        String newRemoteImagesDownPath = remoteImagesDownPath.replace("yyyymmdd", batchDate);
        //文件名
        String fileName = imageFileName.replace("curDate", batchDate);
        String OkFileName =imageOKFileName.replace("curDate", batchDate);
        try {
            // 从前置文件服务器下载文件到本地
            sftpUtil = new SFTPUtil(username, pwd, host, port);
            //校验ok文件
            Vector<ChannelSftp.LsEntry> files = sftpUtil.ls(newRemoteImagesDownPath);
            Objects.requireNonNull(files,"该目录下没有文件");
            StringBuilder sb =new StringBuilder();
            for (ChannelSftp.LsEntry file : files) {
                String filename = file.getFilename();
                sb.append(filename);
            }
            if(!sb.toString().contains(FilePathConstant.OK_SUFFIX)){
                throw new RuntimeException("ok文件不存在");
            }
                //下载dat文件
                logger.info("开始从前置文件服务器下载优e贷影像文件：" + newRemoteImagesDownPath + fileName);
                boolean singleFileDownRes = sftpUtil.downFile(sftpUtil, newRemoteImagesDownPath, fileName, localPath, fileName, false);
                logger.info("前置文件服务器下载优e贷影像文件：" + newRemoteImagesDownPath + fileName + "，结果[" + singleFileDownRes + "]");
                //下载ok文件
                logger.info("前置文件服务器下载优e贷影像文件：" + newRemoteImagesDownPath + OkFileName);
                boolean okFileDownRes = sftpUtil.downFile(sftpUtil, newRemoteImagesDownPath, OkFileName, localPath, OkFileName, false);
                logger.info("前置文件服务器下载优e贷影像文件：" + newRemoteImagesDownPath + OkFileName + "，结果[" + okFileDownRes + "]");
            sync(localPath,fileName);
            fileDownRes=true;
        } catch (Exception e) {
            e.printStackTrace();
            String remark = "前置文件服务器下载优e贷影像文件出现异常，异常信息：" + e.getMessage();
            logger.error(remark);
            throw new RuntimeException("前置文件服务器下载优e贷影像文件出现异常，异常信息：" + e.getMessage());
        } finally {
            if (sftpUtil != null) {
                sftpUtil.closeSFTP();
            }
        }
        long endTime = System.currentTimeMillis();
        logger.info("前置文件服务器获取优e贷影像文件：[" + DateTool.formatDate(new Date(endTime), DateTool.PATTERN_DATETIME) + "]， 处理结束！");
        logger.info("前置文件服务器获取优e贷影像文件：，耗时：[" + (endTime - startTime) / 1000.0 + "]秒！");
        return fileDownRes;
    }

    private boolean sync(String localPath,String localfname) throws Exception {
        boolean result = false;
        boolean uploadFileIsOK = false;
        boolean imageBizDetail = false;
        //文件全路径
        String allFilePath = localPath + localfname;
//        String allFilePath = "G:\\1002000.pub_image_upload.i.20200923.000.dat";
        logger.info( "落表开始，文件路径：" + allFilePath);
        File tranFile = new File(allFilePath);
        // 如果文件存在，则落表
        if (tranFile.exists()) {
            TxtFileLoadPlugin txtFileLoadPlugin = new TxtFileLoadPlugin(allFilePath, "0x02", "UTF-8", 0, 1000);
            List<TxtFileLoadBean> txtFileLoadList = txtFileLoadPlugin.run(new YedImageFileInfo());
            uploadFileIsOK = insertOrupdateUploadFile(txtFileLoadList,localPath,localfname);
            imageBizDetail = insertOrupdateImageBizDetail(txtFileLoadList,localPath,localfname);
            if (txtFileLoadList.size() != 0) {
                while (!txtFileLoadList.get(txtFileLoadList.size() - 1).isReadedComplete) {
                    txtFileLoadPlugin.setFirstRead(false);
                    txtFileLoadList = txtFileLoadPlugin.run(new YedImageFileInfo());
                    if (txtFileLoadList.size() == 0) {
                        break;
                    }
                    uploadFileIsOK = insertOrupdateUploadFile(txtFileLoadList,localPath,localfname);
                    imageBizDetail = insertOrupdateImageBizDetail(txtFileLoadList,localPath,localfname);
                }
            }
            if (uploadFileIsOK && imageBizDetail){
                result = true;
            }
        }
        return result;
    }

    private boolean insertOrupdateUploadFile(List<TxtFileLoadBean> txtFileLoadList,String localPath,String localfname)throws Exception{
        List<YedImageFileInfoVO> yedImageFileInfoList = (List<YedImageFileInfoVO>) beansCopy(txtFileLoadList, YedImageFileInfoVO.class);
        List<UpLoadFileVO> list = new ArrayList<UpLoadFileVO>();
        for (YedImageFileInfoVO imageFileInfo : yedImageFileInfoList) {
            String applySeq=imageFileInfo.getApplySeq();
            //校验授信申请流水号是否存在
            NlsCreditInfoVO nls=new NlsCreditInfoVO();
            nls.setLmtApplySeq(applySeq);
            NlsCreditInfoVO nlsCreditInfoVO = nlsCreditInfoService.queryByPk(nls);
            Objects.requireNonNull(nlsCreditInfoVO,"影像文件中的授信流水号"+applySeq+",在网贷授信表中没有记录！");
            if(!imageFileInfo.getIdentNo().equals(nlsCreditInfoVO.getCertCode())){
                throw new RuntimeException("影像文件中的授信流水号"+applySeq+",与网贷授信表中证件号码不一致！");
            }
            if(!imageFileInfo.getCustNm().equals(nlsCreditInfoVO.getCusName())){
                throw new RuntimeException("影像文件中的授信流水号"+applySeq+",与网贷授信表中姓名不一致！");
            }
            if(StringUtil.isNullorBank(imageFileInfo.getUpLoadTime())){
                throw new RuntimeException("影像文件中的授信流水号"+applySeq+",影像上传时间为空！");
            }
            if(StringUtil.isNullorBank(imageFileInfo.getBatchId())){
                throw new RuntimeException("影像文件中的授信流水号"+applySeq+",影像批次号为空！");
            }
            UpLoadFileVO upLoadFile = new UpLoadFileVO();
            upLoadFile.setApplySeq(applySeq);
            upLoadFile.setImageType(FileNameEnums.map.get("cert_f"));//身份证正面
            upLoadFile.setStartDate(getChangeDate(imageFileInfo.getUpLoadTime()));
            upLoadFile.setState("SUCCESS");
            upLoadFile.setStateNum("");
            upLoadFile.setBatch(imageFileInfo.getBatchId());
            upLoadFile.setFilePath(localPath+localfname);
            upLoadFile.setCreateTime(DateTool.getCurrentDateTime());
            upLoadFile.setLastModifyTime(DateTool.getCurrentDateTime());
            upLoadFile.setAddFileState("");
            upLoadFile.setCertCode(imageFileInfo.getIdentNo());
            upLoadFile.setCusName(imageFileInfo.getCustNm());
            upLoadFile.setPrdName(PrdBizEnums.PrdCodeEnum.PRD_CODE_YED.getDesc());
            list.add(upLoadFile);

            UpLoadFileVO upLoadFile1 = new UpLoadFileVO();
            upLoadFile1.setApplySeq(applySeq);
            upLoadFile1.setImageType(FileNameEnums.map.get("cert_b"));//身份证反面
            upLoadFile1.setStartDate(getChangeDate(imageFileInfo.getUpLoadTime()));
            upLoadFile1.setState("SUCCESS");
            upLoadFile1.setStateNum("");
            upLoadFile1.setBatch(imageFileInfo.getBatchId());
            upLoadFile1.setFilePath(localPath+localfname);
            upLoadFile1.setCreateTime(DateTool.getCurrentDateTime());
            upLoadFile1.setLastModifyTime(DateTool.getCurrentDateTime());
            upLoadFile1.setAddFileState("");
            upLoadFile1.setCertCode(imageFileInfo.getIdentNo());
            upLoadFile1.setCusName(imageFileInfo.getCustNm());
            upLoadFile1.setPrdName(PrdBizEnums.PrdCodeEnum.PRD_CODE_YED.getDesc());
            list.add(upLoadFile1);

            UpLoadFileVO upLoadFile2 = new UpLoadFileVO();
            upLoadFile2.setApplySeq(applySeq);
            upLoadFile2.setImageType(FileNameEnums.map.get("face"));//活体照
            upLoadFile2.setStartDate(getChangeDate(imageFileInfo.getUpLoadTime()));
            upLoadFile2.setState("SUCCESS");
            upLoadFile2.setStateNum("");
            upLoadFile2.setBatch(imageFileInfo.getBatchId());
            upLoadFile2.setFilePath(localPath+localfname);
            upLoadFile2.setCreateTime(DateTool.getCurrentDateTime());
            upLoadFile2.setLastModifyTime(DateTool.getCurrentDateTime());
            upLoadFile2.setAddFileState("");
            upLoadFile2.setCertCode(imageFileInfo.getIdentNo());
            upLoadFile2.setCusName(imageFileInfo.getCustNm());
            upLoadFile2.setPrdName(PrdBizEnums.PrdCodeEnum.PRD_CODE_YED.getDesc());
            list.add(upLoadFile2);
        }
        int i = upLoadFileService.insertOrUpdateUpLoadFileList(list);
        list = null;
        if (i == -1) {
            return false;
        }
        return true;
    }

    private boolean insertOrupdateImageBizDetail(List<TxtFileLoadBean> txtFileLoadList,String localPath,String localfname)throws Exception{
        List<YedImageFileInfoVO> yedImageFileInfoList = (List<YedImageFileInfoVO>) beansCopy(txtFileLoadList, YedImageFileInfoVO.class);
        List<ImageBizDetailVO> list = new ArrayList<ImageBizDetailVO>();
        for (YedImageFileInfoVO imageFileInfo : yedImageFileInfoList) {
            ImageBizDetailVO imageBizDetail = new ImageBizDetailVO();
            imageBizDetail.setApplySeq(imageFileInfo.getApplySeq());
            imageBizDetail.setFileDesc(FileNameEnums.mapImage.get("A01"));
            imageBizDetail.setImageId(FileNameEnums.map.get("cert_f"));
            imageBizDetail.setImageType(FileNameEnums.map.get("cert_f"));//身份证正面
            imageBizDetail.setCreateTime(imageFileInfo.getUpLoadTime());
            imageBizDetail.setLastModifyTime(imageFileInfo.getUpLoadTime());
            imageBizDetail.setFileName(localfname);
            imageBizDetail.setFilePath(localPath+localfname);
            imageBizDetail.setBizStage("");
            list.add(imageBizDetail);

            ImageBizDetailVO imageBizDetail0 = new ImageBizDetailVO();
            imageBizDetail0.setApplySeq(imageFileInfo.getApplySeq());
            imageBizDetail0.setFileDesc(FileNameEnums.mapImage.get("A02"));
            imageBizDetail0.setImageId(FileNameEnums.map.get("cert_b"));
            imageBizDetail0.setImageType(FileNameEnums.map.get("cert_b"));//身份证反面
            imageBizDetail0.setCreateTime(imageFileInfo.getUpLoadTime());
            imageBizDetail0.setLastModifyTime(imageFileInfo.getUpLoadTime());
            imageBizDetail0.setFileName(localfname);
            imageBizDetail0.setFilePath(localPath+localfname);
            imageBizDetail0.setBizStage("");
            list.add(imageBizDetail0);

            ImageBizDetailVO imageBizDetail2 = new ImageBizDetailVO();
            imageBizDetail2.setApplySeq(imageFileInfo.getApplySeq());
            imageBizDetail2.setFileDesc(FileNameEnums.mapImage.get("A03"));
            imageBizDetail2.setImageId(FileNameEnums.map.get("face"));
            imageBizDetail2.setImageType(FileNameEnums.map.get("face"));//活体照
            imageBizDetail2.setCreateTime(imageFileInfo.getUpLoadTime());
            imageBizDetail2.setLastModifyTime(imageFileInfo.getUpLoadTime());
            imageBizDetail2.setFileName(localfname);
            imageBizDetail2.setFilePath(localPath+localfname);
            imageBizDetail2.setBizStage("");
            list.add(imageBizDetail2);

        }
        int i = imageBizDetailService.insertOrUpdateImageBizDetailList(list);
        list = null;
        if (i == -1) {
            return false;
        }
        return true;
    }

    /**返回转换格式"yyyyMMdd"后的日期*/
    private String getChangeDate(String date){
        String dateStr = DateTool.formatDate(DateTool.parseDate(date,"yyyy-MM-dd HH:mm:ss"),"yyyyMMdd");
        return dateStr;
    }

    /**
     * 记录异常信息
     *
     * @param applySeq
     * @param remark
     * @param tableName
     * @param errorType
     * @return
     * @throws Exception
     * @author ludayong
     * @since 2019年1月15日 上午9:23:42
     * @version 1.0
     */
    private void recordLogErrorInfo(String applySeq, String remark, String tableName, String errorType) {
        String currentTime = DateTool.getCurrentDateTime();// 当前时间
        // 错误信息
        LogErrorInfoVO logErrorInfoVo = new LogErrorInfoVO();
        logErrorInfoVo.setSerno(UUIDUtil.getUUID());// 主键
        logErrorInfoVo.setApplySeq(applySeq);
        logErrorInfoVo.setState(ElectronicSignatureEnums.YesNoEnum.NO.VALUE);// 未处理
        logErrorInfoVo.setCreateTime(currentTime);// 创建时间
        logErrorInfoVo.setLastModifyTime(currentTime);// 最后修改时间
        logErrorInfoVo.setTableName(tableName);// 表名
        logErrorInfoVo.setErrorMsg(remark);// 错误信息
        logErrorInfoVo.setRemark(remark);// 备注
        logErrorInfoVo.setErrorType(errorType);// 错误级别
        logErrorInfoService.insertLogErrorInfo(logErrorInfoVo);// 记录错误信息
    }
}
